/*-
 * #%L
 * OBKV Table Client Framework
 * %%
 * Copyright (C) 2021 OceanBase
 * %%
 * OBKV Table Client Framework is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 * #L%
 */

package com.alipay.oceanbase.rpc.temp;

import com.alipay.oceanbase.rpc.util.CRC64;
import com.alipay.remoting.util.CrcUtil;
import io.netty.buffer.ByteBuf;

public class Crc64Util {

    /**
     * CRC-64-ECMA-182
     *
     * @url http://reveng.sourceforge.net/crc-catalogue/17plus.htm
     */
    static final long[] CRC64TABLE = new long[] { 0L, 121597189939003392L, 243194379878006784L,
            202661983231672320L, 486388759756013568L, 535928355657089024L, 405323966463344640L,
            292733975779082240L, 972777519512027136L, 878201927337246720L, 1071856711314178048L,
            1103381908705771520L, 810647932926689280L, 788129934789836800L, 585467951558164480L,
            689050742987685888L, 1945555039024054272L, 1923037040887201792L, 1756403854674493440L,
            1859986646104014848L, 2143713422628356096L, 2049137830453575680L, 2206763817411543040L,
            2238289014803136512L, 1621295865853378560L, 1670835461754454016L, 1576259869579673600L,
            1463669878895411200L, 1170935903116328960L, 1292533093055332352L, 1378101485975371776L,
            1337569089329037312L, 3891110078048108544L, 4012707267987111936L, 3846074081774403584L,
            3805541685128069120L, 3512807709348986880L, 3562347305250062336L, 3719973292208029696L,
            3607383301523767296L, 4287426845256712192L, 4192851253081931776L, 4098275660907151360L,
            4129800858298744832L, 4413527634823086080L, 4391009636686233600L, 4476578029606273024L,
            4580160821035794432L, 3242591731706757120L, 3220073733569904640L, 3341670923508908032L,
            3445253714938429440L, 3152519739159347200L, 3057944146984566784L, 2927339757790822400L,
            2958864955182415872L, 2341871806232657920L, 2391411402133733376L, 2585066186110664704L,
            2472476195426402304L, 2756202971950743552L, 2877800161889746944L, 2675138178658074624L,
            2634605782011740160L, 7782220156096217088L, 7903817346035220480L, 8025414535974223872L,
            7984882139327889408L, 7692148163548807168L, 7741687759449882624L, 7611083370256138240L,
            7498493379571875840L, 7025615418697973760L, 6931039826523193344L, 7124694610500124672L,
            7156219807891718144L, 7439946584416059392L, 7417428586279206912L, 7214766603047534592L,
            7318349394477056000L, 8574853690513424384L, 8552335692376571904L, 8385702506163863552L,
            8489285297593384960L, 8196551321814302720L, 8101975729639522304L, 8259601716597489664L,
            8291126913989083136L, 8827055269646172160L, 8876594865547247616L, 8782019273372467200L,
            8669429282688204800L, 8953156059212546048L, 9074753249151549440L, 9160321642071588864L,
            9119789245425254400L, 6485183463413514240L, 6606780653352517632L, 6440147467139809280L,
            6399615070493474816L, 6683341847017816064L, 6732881442918891520L, 6890507429876858880L,
            6777917439192596480L, 6305039478318694400L, 6210463886143913984L, 6115888293969133568L,
            6147413491360727040L, 5854679515581644800L, 5832161517444792320L, 5917729910364831744L,
            6021312701794353152L, 4683743612465315840L, 4661225614328463360L, 4782822804267466752L,
            4886405595696988160L, 5170132372221329408L, 5075556780046548992L, 4944952390852804608L,
            4976477588244398080L, 5512405943901487104L, 5561945539802562560L, 5755600323779493888L,
            5643010333095231488L, 5350276357316149248L, 5471873547255152640L, 5269211564023480320L,
            5228679167377145856L, -2882303761517117440L, -2760706571578114048L,
            -2639109381639110656L, -2679641778285445120L, -2395915001761103872L,
            -2346375405860028416L, -2476979795053772800L, -2589569785738035200L,
            -3062447746611937280L, -3157023338786717696L, -2963368554809786368L,
            -2931843357418192896L, -3224577333197275136L, -3247095331334127616L,
            -3449757314565799936L, -3346174523136278528L, -4395513236313604096L,
            -4418031234450456576L, -4584664420663164928L, -4481081629233643520L,
            -4197354852709302272L, -4291930444884082688L, -4134304457926115328L,
            -4102779260534521856L, -3566850904877432832L, -3517311308976357376L,
            -3611886901151137792L, -3724476891835400192L, -4017210867614482432L,
            -3895613677675479040L, -3810045284755439616L, -3850577681401774080L,
            -1297036692682702848L, -1175439502743699456L, -1342072688956407808L,
            -1382605085602742272L, -1675339061381824512L, -1625799465480749056L,
            -1468173478522781696L, -1580763469207044096L, -2053641430080946176L,
            -2148217022255726592L, -2242792614430507008L, -2211267417038913536L,
            -1927540640514572288L, -1950058638651424768L, -1864490245731385344L,
            -1760907454301863936L, -792633534417207296L, -815151532554059776L,
            -693554342615056384L, -589971551185534976L, -882705526964617216L, -977281119139397632L,
            -1107885508333142016L, -1076360310941548544L, -540431955284459520L,
            -490892359383384064L, -297237575406452736L, -409827566090715136L, -126100789566373888L,
            -4503599627370496L, -207165582859042816L, -247697979505377280L, -5476377146882523136L,
            -5354779956943519744L, -5233182767004516352L, -5273715163650850816L,
            -5566449139429933056L, -5516909543528857600L, -5647513932722601984L,
            -5760103923406864384L, -5080060379673919488L, -5174635971848699904L,
            -4980981187871768576L, -4949455990480175104L, -4665729213955833856L,
            -4688247212092686336L, -4890909195324358656L, -4787326403894837248L,
            -5836665117072162816L, -5859183115209015296L, -6025816301421723648L,
            -5922233509992202240L, -6214967485771284480L, -6309543077946064896L,
            -6151917090988097536L, -6120391893596504064L, -6737385042546262016L,
            -6687845446645186560L, -6782421038819966976L, -6895011029504229376L,
            -6611284252979888128L, -6489687063040884736L, -6404118670120845312L,
            -6444651066767179776L, -9079256848778919936L, -8957659658839916544L,
            -9124292845052624896L, -9164825241698959360L, -8881098465174618112L,
            -8831558869273542656L, -8673932882315575296L, -8786522872999837696L,
            -8106479329266892800L, -8201054921441673216L, -8295630513616453632L,
            -8264105316224860160L, -8556839292003942400L, -8579357290140794880L,
            -8493788897220755456L, -8390206105791234048L, -7421932185906577408L,
            -7444450184043429888L, -7322852994104426496L, -7219270202674905088L,
            -6935543426150563840L, -7030119018325344256L, -7160723407519088640L,
            -7129198210127495168L, -7746191359077253120L, -7696651763176177664L,
            -7502996979199246336L, -7615586969883508736L, -7908320945662590976L,
            -7786723755723587584L, -7989385738955259904L, -8029918135601594368L };

    public static long updateChecksum(long before, byte[] bytes) {
        return updateChecksum(before, bytes, 0, bytes.length);

    }

    public static long updateChecksum(long before, byte[] bytes, int from, int to) {
        if (to == 0) {
            return before;
        } else {
            int max = from + to;

            for (int i = from; i < max; ++i) {
                int tmp = ((int) before ^ bytes[i]) & 255;
                before = before >>> 8 ^ CRC64TABLE[tmp];
            }

            return before;
        }
    }

    public static long updateChecksum(long before, ByteBuf bytes) {
        int max = bytes.readableBytes();
        bytes.markReaderIndex();
        try {
            if (max == 0) {
                return before;
            } else {
                while (max-- > 0) {
                    int tmp = ((int) before ^ bytes.readByte()) & 255;
                    before = before >>> 8 ^ CRC64TABLE[tmp];
                }

                return before;
            }
        } finally {
            bytes.resetReaderIndex();
        }
    }

    public static long updateChecksum(long before, long updateNew) {
        int var4 = 0;

        for (int var5 = 0; var5 < 8; ++var5) {
            byte var6 = (byte) ((int) (updateNew >> var4 & 255L));
            int var7 = ((int) before ^ var6) & 255;
            before = before >>> 8 ^ CRC64TABLE[var7];
            var4 += 8;
        }

        return before;
    }

    public static void main(String[] args) {
        long t = updateChecksum(0, "hello".getBytes());
        System.out.println(t);
        System.out.println(updateChecksum(t, "world".getBytes()));
        System.out.println(updateChecksum(0, "helloworld".getBytes()));

        CRC64 crc64 = new CRC64();
        crc64.update("helloworld".getBytes());
        System.err.println(crc64.getValue());

        System.err.println(CrcUtil.crc32("helloworld".getBytes()));
    }

}
